home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / WINPROGS / WINSRC20.ZIP / NEWTON.ASM < prev    next >
Assembly Source File  |  1990-07-09  |  6KB  |  335 lines

  1. ; NEWTON.ASM : Procedure NewtonFractal() from FRACTINT.
  2. ; Lee Daniel Crocker, 4/23/89.
  3. ;
  4. ; Tabs: 8
  5. ;
  6. ; Modifications:
  7. ;   BT = Bert Tyler
  8. ;   TW = Timothy Wegner
  9. ;   RD = Robert Day
  10. ;   MP = Mark Peterson
  11. ;
  12. ; Note: newton.asm was totally rewritten by Lee Crocker for FRACTINT 10.0
  13. ;    for integration with the newly structured fractal engine in calcmand.c
  14. ;    and fractals.c. The current routine consists of the inner orbit
  15. ;    calculation, with the supporting code removed. Early versions of
  16. ;    newton.asm contained a complete newton fractal function.
  17. ;
  18. ; Assembled by Microsoft Macro Assembler 5.1, for use with Microsoft C 5.1.
  19. ;
  20.  
  21. ; Required for compatibility if Turbo ASM (BT 5/20/89)
  22.  
  23. IFDEF ??version
  24. MASM51
  25. QUIRKS
  26. EMUL
  27. ENDIF
  28.  
  29. .model    medium, c
  30.  
  31. public    NewtonFractal2
  32. public    invertz2
  33.  
  34. .data
  35.     extrn    color:word, maxcolor:word, degree:word, basin:word
  36.     extrn    row:word, col:word
  37.  
  38.     extrn    dx0:dword, dy0:dword
  39.     extrn    dx1:dword, dy1:dword
  40.  
  41.     extrn    old:qword, new:qword, d1overd:qword, roverd:qword
  42.     extrn    threshold:qword, floatmin:qword, floatmax:qword
  43.     extrn    f_radius:qword, f_xcenter:qword, f_ycenter:qword
  44.     extrn    roots:word, tempsqrx:qword
  45.  
  46. statw    dw    ?
  47.  
  48. .code
  49.  
  50. public    NewtonFractal2
  51. NewtonFractal2 proc
  52.  
  53. ;
  54. ; cpower(&old, degree-1, &tmp)
  55. ;
  56.     mov    ax, degree
  57.     dec    ax
  58.  
  59.     fld    old + 8
  60.     fld    old
  61. ;
  62. ; cpower() is expanded inline here.
  63. ;
  64.     shr    ax, 1
  65.     jnc    load1            ; if (exp & 1)
  66.  
  67.     fld    st(1)
  68.     fld    st(1)
  69.     jmp    short looptop        ; tmp = old
  70. load1:
  71.     fldz
  72.     fld1                ; else tmp = [1,0]
  73. looptop:
  74.     cmp    ax, 0
  75.     je    loopexit        ; while (exp)
  76.  
  77.     fld    st(2)            ; RD 5/7/89: Calculate xt^2 - yt^2
  78.     fadd    st, st(4)        ; by using (xt+yt)*(xt-yt), which
  79.     fld    st(3)            ; trades one multiplication for an
  80.     fsub    st, st(5)        ; addition.  This trick saves a
  81.     fmul                ; whopping 1.2% of time.
  82.  
  83.     fld    st(4)
  84.     fmul    st, st(4)
  85.     fadd    st, st            ; yt = 2 * xt * yt
  86.  
  87.     fstp    st(5)            ; tmp.y = yt
  88.     fstp    st(3)            ; tmp.x = xt
  89.  
  90.     shr    ax, 1
  91.     jnc    looptop         ; if (exp & 1)
  92.  
  93.     fld    st(2)
  94.     fmul    st, st(1)
  95.     fld    st(4)
  96.     fmul    st, st(3)
  97.     fsub                ; tmp.x = xt * tmp.x - yt * tmp.y
  98.  
  99.     fld    st(3)
  100.     fmul    st, st(3)
  101.     fld    st(5)
  102.     fmul    st, st(3)
  103.     fadd                ; tmp.y = xt * tmp.y + yt * tmp.x
  104.     fstp    st(3)
  105.     fstp    st(1)
  106.  
  107.     jmp    short looptop
  108. loopexit:
  109.     fstp    st(2)
  110.     fstp    st(2)
  111. ;
  112. ; End of complex_power() routine.  Result is in ST, ST(1)
  113. ;
  114. ;
  115. ; complex_mult(tmp, old, &new);
  116. ;
  117.     fld    old + 8
  118.     fld    old
  119.  
  120.     fld    st(3)        ; tmp.y
  121.     fmul    st, st(1)   ; old.x
  122.     fld    st(3)        ; tmp.x
  123.     fmul    st, st(3)   ; old.y
  124.     fadd
  125.     fld    st(3)        ; tmp.x
  126.     fmul    st, st(2)   ; old.x
  127.     fld    st(5)        ; tmp.y
  128.     fmul    st, st(4)   ; old.y
  129.     fsub
  130. ;
  131. ; if (DIST1(new) < THRESHOLD) {
  132. ;
  133.     fld1
  134.     fsubr    st, st(1)
  135.     fmul    st, st
  136.     fld    st(2)        ; new.y
  137.     fmul    st, st
  138.     fadd
  139.     fcomp    threshold
  140.     fstsw    statw
  141.     mov    ax, statw
  142.     sahf
  143.     jnc    notless
  144. ;
  145. ; if (fractype == NEWTBASIN) {
  146. ;
  147.     mov    ax, basin
  148.     cmp    ax, 0
  149.     je    notbasin
  150.  
  151.     mov    bx, roots
  152.     mov    dx, -1            ; tempcolor = -1
  153.     sub    cx, cx
  154. dloop:
  155.     fld    qword ptr [bx]    ; roots[i].x
  156.     fsub    st, st(3)    ; old.x
  157.     fmul    st, st
  158.     fld    qword ptr [bx+8]; roots[i].y
  159.     fsub    st, st(5)    ; old.y
  160.     fmul    st, st
  161.     fadd
  162.     fcomp    threshold
  163.     fstsw    statw
  164.     mov    ax, statw
  165.     sahf                ; if (distance(roots[i],old) < threshold)...
  166.     jnc    nl2
  167.  
  168. ; TW commented out next few lines and add dx,ax to eliminate newtbasin
  169. ; color shades per Phil Wilson's request 12/03/89
  170.  
  171. ; TW put it back in in response to another use as an option! 7/7/90
  172.     mov    dx, cx
  173.     cmp    basin,2            ; basin==2 is flag for stripes
  174.     jne    nostripes
  175.     mov    ax, color
  176.     and    ax, 1
  177.     shl    ax, 1
  178.     shl    ax, 1
  179.     shl    ax, 1
  180.  
  181.     and    dx, 7
  182.     add    dx, ax
  183. nostripes:
  184.     inc    dx            ; tempcolor = 1+(i&7)+((color&1)<<3)
  185.     jmp    short nfb        ; break
  186. nl2:
  187.     add    bx, 16
  188.     inc    cx
  189.     cmp    cx, degree
  190.     jl    dloop
  191. nfb:
  192.     mov    ax, dx
  193.     cmp    dx, -1
  194.     jne    notm1
  195.     mov    ax, maxcolor        ; if (tmpcolor == -1)...
  196. notm1:
  197.     mov    color, ax
  198. notbasin:
  199.     mov    ax, 1
  200.     jmp    nlexit
  201. notless:
  202.     fld    d1overd
  203.     fmul    st(2), st        ; new.y *= d1overd
  204.     fmul
  205.     fld    roverd
  206.     fadd                ; new.x = d1overd * new.x + roverd
  207.  
  208.     fld    st(5)        ; tmp.y
  209.     fmul    st, st
  210.     fld    st(5)        ; tmp.x
  211.     fmul    st, st
  212.     fadd
  213.     fcom    floatmin
  214.     fstsw    statw
  215.     mov    ax, statw
  216.     sahf                ; if (mod(tmp) < FLT_MIN) {
  217.     jnc    cont
  218.     mov    ax, 1
  219.     fstp    st
  220.     jmp    nlexit
  221. cont:
  222.     fld1
  223.     fdivr
  224.     fst    st(4)        ; old.y
  225.     fstp    st(3)        ; old.x
  226.  
  227.     fld    st(4)        ; tmp.x
  228.     fmul    st, st(1)   ; new.x
  229.     fld    st(6)        ; tmp.y
  230.     fmul    st, st(3)   ; new.y
  231.     fadd
  232.     fmulp    st(3), st   ; old.x
  233.  
  234.     fld    st(4)        ; tmp.x
  235.     fmul    st, st(2)   ; new.y
  236.     fld    st(6)        ; tmp.y
  237.     fmul    st, st(2)   ; new.x
  238.     fsub
  239.     fmulp    st(4), st   ; old.y    ; old = new / tmp
  240.  
  241.     fstp    new
  242.     fstp    new + 8
  243.     fstp    old
  244.     fstp    old + 8
  245.     mov    ax, 0
  246.     jmp    nlx2
  247. nlexit:
  248.     fstp    new
  249.     fstp    new + 8
  250.     fstp    st
  251.     fstp    st
  252. nlx2:
  253.     fstp    st
  254.     fstp    st
  255.  
  256.     ret
  257. NewtonFractal2 endp
  258. ;
  259. ;
  260. ;
  261. public    invertz2
  262. invertz2 proc    uses si, zval:word    ; TW 11/03/89 changed zval to near
  263.  
  264.     fld    f_xcenter
  265.     fld    f_ycenter
  266.  
  267.     mov    bx, col
  268.     shl    bx, 1
  269.     shl    bx, 1
  270.     shl    bx, 1
  271.  
  272.     mov    cx, row
  273.     shl    cx, 1
  274.     shl    cx, 1
  275.     shl    cx, 1
  276.  
  277.     mov    ax, ds
  278.     lds    si, dx0
  279.     add    si, bx
  280.     fld    qword ptr [si]
  281.     mov    ds, ax
  282.     lds    si, dx1
  283.     add    si, cx
  284.     fld    qword ptr [si]
  285.     fadd
  286.     fsub    st, st(2)
  287.  
  288.     mov    ds, ax
  289.     lds    si, dy0
  290.     add    si, cx
  291.     fld    qword ptr [si]
  292.     mov    ds, ax
  293.     lds    si, dy1
  294.     add    si, bx
  295.     fld    qword ptr [si]
  296.     fadd
  297.     fsub    st, st(2)
  298.  
  299.     mov    ds, ax
  300.     fld    st(1)
  301.     fmul    st, st
  302.     fld    st(1)
  303.     fmul    st, st
  304.     fadd
  305.  
  306.     fcom    floatmin
  307.     fstsw    statw
  308.     mov    ax, statw
  309.     sahf
  310.     jnc    inl1
  311.  
  312.     fstp    st
  313.     fld    floatmax
  314.     jmp    icom
  315. inl1:
  316.     fld    f_radius
  317.     fdivr
  318. icom:
  319.     fst    tempsqrx
  320.  
  321.     fmul    st(2), st
  322.     fmul
  323.     faddp    st(2), st
  324.     faddp    st(2), st
  325.  
  326. ;    lds    si, zval    ; TW 11/03/89 zval is now a near pointer
  327.     mov    si, zval    ; TW
  328.     fstp    qword ptr [si+8]
  329.     fstp    qword ptr [si]
  330.  
  331.     ret
  332. invertz2 endp
  333.  
  334. END
  335.